#include <lvgl.h>
#include "gui.h"
#include "common.h"

typedef enum {
  USB_PAGE_MONITOR = 0,
  USB_PAGE_SETTING,
} USB_PAGE_ENUM;

#define USB_HUB_HWMON_UPDATE_INV 200
#define USB_HUB_BTN_WIDTH 234
#define USB_HUB_BTN_HEIGHT 234

#define HIGHLIGHT_COLOR 0x00CC65
#define CURRENT_COLOR 0x80d9b0
#define VOLTAGE_COLOR 0xcb7777
#define POWER_COLOR 0x8698c0
#define TIPS_TEXT_COLOR 0xa3a3a3
#define BORDER_COLOR 0x808080

#define PORT_FAIL_COLOR 0x804e81
#define PORT_NORMAL_COLOR 0x0
#define PORT_OFF_COLOR 0x505050
#define PORT_ALERT_COLOR 0xb47254
#define PORT_OC_COLOR 0xbe4a58

const uint32_t port_status_color[5]{ PORT_FAIL_COLOR, PORT_NORMAL_COLOR, PORT_OFF_COLOR, PORT_ALERT_COLOR, PORT_OC_COLOR };

#define CHART_TEMP_LEN 79
#define CHART_COLOR 0x00CC65
#define CHART_LINE_COLOR 0xffffff

#define MAIN_BIG_NUM_FONT FontNums_36
#define TIPS_FONT FontTips_12
#define SETTING_TIPS_FONT FontSYHT_16

LV_FONT_DECLARE(MAIN_BIG_NUM_FONT);
LV_FONT_DECLARE(TIPS_FONT);
LV_FONT_DECLARE(SETTING_TIPS_FONT);

static const char *kb_map[] = { "1", "2", "3", "\n", "4", "5", "6", "\n", "7", "8", "9", "\n", LV_SYMBOL_BACKSPACE, "0", LV_SYMBOL_OK, NULL };
static const lv_btnmatrix_ctrl_t kb_ctrl[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static const char *const tips[4]{ "端口告警电流", "端口断开电流", "图表最小电流", "图表最大电流" };

static lv_timer_t *_usb_hub_timer = NULL;
static lv_obj_t *screen_usb_hub = NULL;
static lv_obj_t *btn_usb[USB_PORT_NUMS] = { NULL };
static lv_obj_t *lb_voltage[USB_PORT_NUMS] = { NULL };
static lv_obj_t *lb_current[USB_PORT_NUMS] = { NULL };
static lv_obj_t *lb_power[USB_PORT_NUMS] = { NULL };
static lv_obj_t *lb_status[USB_PORT_NUMS] = { NULL };
static lv_obj_t *chartCurrent[USB_PORT_NUMS] = { NULL };
static lv_chart_series_t *chartCurrentSer[USB_PORT_NUMS] = { NULL };
static lv_obj_t *ta_setting[4] = { NULL };
static lv_obj_t *kb = NULL;
static lv_obj_t *main_cont = NULL;
static lv_obj_t *setting_cont = NULL;
static lv_obj_t *usb_cont = NULL;
static lv_obj_t *lb_ctt = NULL;

static lv_anim_t page_anim;

static bool page_animating = false;
static uint8_t btnState[USB_PORT_NUMS] = { USB_PORT_ON };
static uint8_t curr_page = USB_PAGE_MONITOR;
static uint8_t curr_setting_port = 0;

static lv_style_t btn_style;
static lv_style_t voltage_style;
static lv_style_t current_style;
static lv_style_t power_style;
static lv_style_t status_style;
static lv_style_t lb_mark_style;
static lv_style_t num_style;
static lv_style_t style_radio;
static lv_style_t style_radio_chk;
static lv_style_t style_text_area;
static lv_style_t style_text_area_focus;
static lv_style_t style_label;

static void draw_current_setting(int index = -1) {
  char txt[10] = { 0 };
  if (index < 0) {
    snprintf(txt, 10, "%d", inaData[curr_setting_port].currAlert);
    lv_textarea_set_text(ta_setting[0], txt);

    snprintf(txt, 10, "%d", inaData[curr_setting_port].currCutOff);
    lv_textarea_set_text(ta_setting[1], txt);

    snprintf(txt, 10, "%d", inaData[curr_setting_port].chartMin);
    lv_textarea_set_text(ta_setting[2], txt);

    snprintf(txt, 10, "%d", inaData[curr_setting_port].chartMax);
    lv_textarea_set_text(ta_setting[3], txt);
  } else if (index == 0) {
    snprintf(txt, 10, "%d", inaData[curr_setting_port].currAlert);
    lv_textarea_set_text(ta_setting[0], txt);
  } else if (index == 1) {
    snprintf(txt, 10, "%d", inaData[curr_setting_port].currCutOff);
    lv_textarea_set_text(ta_setting[1], txt);
  } else if (index == 2) {
    snprintf(txt, 10, "%d", inaData[curr_setting_port].chartMin);
    lv_textarea_set_text(ta_setting[2], txt);
  } else if (index == 3) {
    snprintf(txt, 10, "%d", inaData[curr_setting_port].chartMax);
    lv_textarea_set_text(ta_setting[3], txt);
  }
}

static void port_radio_event_handler(lv_event_t *e) {
  lv_obj_t *cont = lv_event_get_current_target(e);
  lv_obj_t *act_cb = lv_event_get_target(e);
  lv_obj_t *old_cb = lv_obj_get_child(cont, curr_setting_port);

  if (act_cb == cont)
    return;

  lv_obj_clear_state(old_cb, LV_STATE_CHECKED);
  lv_obj_add_state(act_cb, LV_STATE_CHECKED);

  curr_setting_port = lv_obj_get_index(act_cb);
  draw_current_setting();
}

static void ta_event_cb(lv_event_t *e) {
  lv_event_code_t code = lv_event_get_code(e);
  lv_obj_t *ta = lv_event_get_target(e);
  if (code == LV_EVENT_CLICKED || code == LV_EVENT_FOCUSED) {

    if (kb != NULL)
      lv_keyboard_set_textarea(kb, ta);
  } else if (code == LV_EVENT_READY) {
    int current[4] = { 0 };
    current[0] = inaData[curr_setting_port].currAlert;
    current[1] = inaData[curr_setting_port].currCutOff;
    current[2] = inaData[curr_setting_port].chartMin;
    current[3] = inaData[curr_setting_port].chartMax;

    for (int i = 0; i < 4; i++) {
      String v = String(lv_textarea_get_text(ta_setting[i]));
      if (v == "") {
        draw_current_setting(i);
      } else {
        int value = v.toInt();
        if (value < 0 || value > 2000) {
          lv_label_set_text(lb_ctt, "值超出范围(0-2000)");
          return;
        }
        current[i] = value;
      }
    }
    // 已更新4个值，开始判定

    // 判断警告电流小于端口断开电流
    if (current[0] < current[1]) {
      inaData[curr_setting_port].currAlert = current[0];
      inaData[curr_setting_port].currCutOff = current[1];
    } else {
      lv_label_set_text(lb_ctt, "告警电流必须小于断开电流");
      return;
    }

    // 判断图表
    if (current[2] < current[3]) {
      inaData[curr_setting_port].chartMin = current[2];
      inaData[curr_setting_port].chartMax = current[3];
      lv_chart_set_range(chartCurrent[curr_setting_port], LV_CHART_AXIS_PRIMARY_Y, inaData[curr_setting_port].chartMin, inaData[curr_setting_port].chartMax);
    } else {
      lv_label_set_text(lb_ctt, "图表最小电流必须小于最大电流");
      return;
    }
    lv_label_set_text(lb_ctt, "");
    saveConfigToNVS();
  }
}

static void radiobutton_create(lv_obj_t *parent, const char *txt) {
  lv_obj_t *obj = lv_checkbox_create(parent);
  lv_checkbox_set_text(obj, txt);
  lv_obj_remove_style_all(obj);
  lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);
  lv_obj_add_style(obj, &style_radio, LV_PART_MAIN);

  lv_style_selector_t sel = (int)LV_PART_MAIN | LV_STATE_CHECKED;
  lv_obj_add_style(obj, &style_radio_chk, sel);
}

static void set_port_btn_status(uint8_t num, uint8_t status) {
  if (num >= USB_PORT_NUMS)
    return;

  if (status == USB_PORT_ON) {
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_1);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_2);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_3);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_4);

    lv_obj_clear_state(lb_voltage[num], LV_STATE_USER_1);
    lv_obj_clear_state(lb_current[num], LV_STATE_USER_1);
    lv_obj_clear_state(lb_power[num], LV_STATE_USER_1);
  } else if (status == USB_PORT_OFF) {
    lv_obj_add_state(btn_usb[num], LV_STATE_USER_1);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_2);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_3);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_4);

    lv_obj_add_state(lb_voltage[num], LV_STATE_USER_1);
    lv_obj_add_state(lb_current[num], LV_STATE_USER_1);
    lv_obj_add_state(lb_power[num], LV_STATE_USER_1);
  } else if (status == USB_PORT_ALERT) {
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_1);
    lv_obj_add_state(btn_usb[num], LV_STATE_USER_2);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_3);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_4);

    lv_obj_clear_state(lb_voltage[num], LV_STATE_USER_1);
    lv_obj_clear_state(lb_current[num], LV_STATE_USER_1);
    lv_obj_clear_state(lb_power[num], LV_STATE_USER_1);
  } else if (status == USB_PORT_OC) {
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_1);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_2);
    lv_obj_add_state(btn_usb[num], LV_STATE_USER_3);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_4);

    lv_obj_clear_state(lb_voltage[num], LV_STATE_USER_1);
    lv_obj_clear_state(lb_current[num], LV_STATE_USER_1);
    lv_obj_clear_state(lb_power[num], LV_STATE_USER_1);
  } else {
    // FAIL
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_1);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_2);
    lv_obj_clear_state(btn_usb[num], LV_STATE_USER_3);
    lv_obj_add_state(btn_usb[num], LV_STATE_USER_4);

    lv_obj_add_state(lb_voltage[num], LV_STATE_USER_1);
    lv_obj_add_state(lb_current[num], LV_STATE_USER_1);
    lv_obj_add_state(lb_power[num], LV_STATE_USER_1);
  }
}

static void set_pos_value(void *obj, int32_t v) {
  lv_obj_align((lv_obj_t *)obj, LV_ALIGN_TOP_LEFT, v, 0);
}

static void page_switch_cb(lv_anim_t *a) {
  page_animating = false;
}

static void change_page() {
  if (page_animating)
    return;

  int begin_pos = 0;
  int tar_pos = 0;
  if (curr_page == USB_PAGE_MONITOR) {
    curr_page = USB_PAGE_SETTING;
    begin_pos = 0;
    tar_pos = -SCREEN_RES_HOR;
  } else {
    curr_page = USB_PAGE_MONITOR;
    begin_pos = -SCREEN_RES_HOR;
    tar_pos = 0;
  }

  lv_anim_del(main_cont, set_pos_value);
  lv_anim_init(&page_anim);
  lv_anim_set_exec_cb(&page_anim, set_pos_value);
  lv_anim_set_values(&page_anim, begin_pos, tar_pos);
  lv_anim_set_deleted_cb(&page_anim, page_switch_cb);
  lv_anim_set_ready_cb(&page_anim, page_switch_cb);
  lv_anim_set_repeat_count(&page_anim, 0);
  lv_anim_set_time(&page_anim, 300);
  lv_anim_set_var(&page_anim, main_cont);
  lv_anim_start(&page_anim);
  page_animating = true;
}

static void btn_event_handler(lv_event_t *e) {
  void *usr_data = lv_event_get_user_data(e);
  lv_obj_t *target = lv_event_get_target(e);
  uint8_t btnid = 0;
  for (int i = 0; i < USB_PORT_NUMS; i++) {
    if (target == btn_usb[i]) {
      btnid = i;
      break;
    }
  }

  if (NULL != usr_data) {
    InaData *idata = (InaData *)usr_data;
    if (idata->portStatus == USB_PORT_ON || idata->portStatus == USB_PORT_ALERT) {
      idata->portStatus = USB_PORT_OFF;
      set_port_btn_status(btnid, idata->portStatus);
      // 切断电路
      switch_usb_port(btnid, false);
    } else if (idata->portStatus == USB_PORT_OC) {
      idata->portStatus = USB_PORT_OFF;
      set_port_btn_status(btnid, idata->portStatus);
      // 单纯转换状态
    } else if (idata->portStatus == USB_PORT_OFF) {
      idata->portStatus = USB_PORT_ON;
      set_port_btn_status(btnid, idata->portStatus);
      // 打开电路
      switch_usb_port(btnid, true);
    }
  }
}

static void usb_hub_timer_timeout(lv_timer_t *timer) {
  refresh_usb_power_hwmon();
  for (int i = 0; i < USB_PORT_NUMS; i++) {
    if (inaData[i].portStatus == USB_PORT_FAIL) {
      continue;
    }

    if (btnState[i] != inaData[i].portStatus) {
      btnState[i] = inaData[i].portStatus;
      set_port_btn_status(i, btnState[i]);
    }
    if (inaData[i].voltage >= 0)
      lv_label_set_text_fmt(lb_voltage[i], "%d.%03d V", inaData[i].voltage / 1000, inaData[i].voltage % 1000);
    else
      lv_label_set_text_fmt(lb_voltage[i], "-%d.%02d V", (-inaData[i].voltage) / 1000, (-inaData[i].voltage) % 1000);

    if (inaData[i].current >= 0)
      lv_label_set_text_fmt(lb_current[i], "%d.%03d A", inaData[i].current / 1000, inaData[i].current % 1000);
    else
      lv_label_set_text_fmt(lb_current[i], "-%d.%02d A", (-inaData[i].current) / 1000, (-inaData[i].current) % 1000);

    if (inaData[i].power >= 0)
      lv_label_set_text_fmt(lb_power[i], "%d.%03d W", inaData[i].power / 1000, inaData[i].power % 1000);
    else
      lv_label_set_text_fmt(lb_power[i], "-%d.%02d W", (-inaData[i].power) / 1000, (-inaData[i].power) % 1000);

    if (btnState[i] == USB_PORT_ON || btnState[i] == USB_PORT_ALERT) {
      lv_chart_set_next_value(chartCurrent[i], chartCurrentSer[i], inaData[i].current);
    }
  }
}

static void chart_draw_event_cb(lv_event_t *e) {
  lv_obj_t *obj = lv_event_get_target(e);

  void *usr_data = lv_event_get_user_data(e);
  uint8_t status = USB_PORT_ON;
  if (NULL != usr_data) {
    InaData *idata = (InaData *)usr_data;
    status = idata->portStatus;
  }

  lv_obj_draw_part_dsc_t *dsc = lv_event_get_draw_part_dsc(e);
  if (dsc->part == LV_PART_ITEMS) {
    if (!dsc->p1 || !dsc->p2)
      return;
    // 先绘制底部的填充遮罩
    lv_draw_mask_line_param_t line_mask_param;
    lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
    int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);

    lv_draw_rect_dsc_t draw_rect_dsc;
    lv_draw_rect_dsc_init(&draw_rect_dsc);
    draw_rect_dsc.bg_opa = LV_OPA_COVER;
    if (status == USB_PORT_ALERT) {
      draw_rect_dsc.bg_color = lv_color_hex(PORT_ALERT_COLOR);
    } else if (status == USB_PORT_OC) {
      draw_rect_dsc.bg_color = lv_color_hex(PORT_OC_COLOR);
    } else {
      draw_rect_dsc.bg_color = lv_color_hex(CHART_COLOR);
    }

    lv_area_t a;
    a.x1 = dsc->p1->x;
    a.x2 = dsc->p2->x - 1;
    a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
    a.y2 = obj->coords.y2;
    lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
    lv_draw_mask_free_param(&line_mask_param);
    lv_draw_mask_remove_id(line_mask_id);
  }
}

static void page_event_handler(lv_event_t *e) {
  lv_event_code_t code = lv_event_get_code(e);
  if (code == LV_EVENT_GESTURE) {
    lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
    lv_indev_wait_release(lv_indev_get_act());
    if (dir == LV_DIR_LEFT || dir == LV_DIR_RIGHT) {
      change_page();
    }
  }
}

static void setup_screen_usb_hub() {
  screen_usb_hub = lv_obj_create(NULL);
  lv_obj_remove_style(screen_usb_hub, NULL, LV_PART_SCROLLBAR);
  lv_obj_set_scrollbar_mode(screen_usb_hub, LV_SCROLLBAR_MODE_OFF);
  lv_obj_set_style_bg_color(screen_usb_hub, lv_color_hex(0x101010), 0);
  lv_obj_set_style_bg_opa(screen_usb_hub, LV_OPA_COVER, 0);
  lv_obj_clear_flag(screen_usb_hub, LV_OBJ_FLAG_SCROLLABLE);

  lv_style_init(&btn_style);
  lv_style_init(&voltage_style);
  lv_style_init(&current_style);
  lv_style_init(&power_style);
  lv_style_init(&status_style);
  lv_style_init(&lb_mark_style);
  lv_style_init(&num_style);
  lv_style_init(&style_radio);
  lv_style_init(&style_radio_chk);
  lv_style_init(&style_text_area);
  lv_style_init(&style_text_area_focus);
  lv_style_init(&style_label);

  lv_style_set_width(&btn_style, USB_HUB_BTN_WIDTH);
  lv_style_set_height(&btn_style, USB_HUB_BTN_HEIGHT);
  lv_style_set_border_width(&btn_style, 0);
  lv_style_set_radius(&btn_style, 0);
  lv_style_set_bg_opa(&btn_style, LV_OPA_COVER);
  lv_style_set_bg_color(&btn_style, lv_color_hex(PORT_NORMAL_COLOR));
  lv_style_set_text_color(&btn_style, lv_color_hex(0x878787));
  lv_style_set_outline_width(&btn_style, 0);
  lv_style_set_shadow_width(&btn_style, 0);
  lv_style_set_pad_ver(&btn_style, 10);
  lv_style_set_pad_hor(&btn_style, 10);

  lv_style_set_text_font(&voltage_style, &MAIN_BIG_NUM_FONT);
  lv_style_set_bg_opa(&voltage_style, LV_OPA_COVER);
  lv_style_set_bg_color(&voltage_style, lv_color_black());
  lv_style_set_width(&voltage_style, 158);
  lv_style_set_height(&voltage_style, 44);
  lv_style_set_text_color(&voltage_style, lv_color_hex(VOLTAGE_COLOR));
  lv_style_set_border_color(&voltage_style, lv_color_hex(BORDER_COLOR));
  lv_style_set_border_opa(&voltage_style, LV_OPA_50);
  lv_style_set_border_width(&voltage_style, 1);
  lv_style_set_pad_top(&voltage_style, 7);
  lv_style_set_pad_left(&voltage_style, 10);

  lv_style_set_text_font(&current_style, &MAIN_BIG_NUM_FONT);
  lv_style_set_bg_opa(&current_style, LV_OPA_COVER);
  lv_style_set_bg_color(&current_style, lv_color_black());
  lv_style_set_width(&current_style, 158);
  lv_style_set_height(&current_style, 44);
  lv_style_set_text_color(&current_style, lv_color_hex(CURRENT_COLOR));
  lv_style_set_border_color(&current_style, lv_color_hex(BORDER_COLOR));
  lv_style_set_border_opa(&current_style, LV_OPA_50);
  lv_style_set_border_width(&current_style, 1);
  lv_style_set_pad_top(&current_style, 7);
  lv_style_set_pad_left(&current_style, 10);

  lv_style_set_text_font(&power_style, &MAIN_BIG_NUM_FONT);
  lv_style_set_bg_opa(&power_style, LV_OPA_COVER);
  lv_style_set_bg_color(&power_style, lv_color_black());
  lv_style_set_width(&power_style, 158);
  lv_style_set_height(&power_style, 44);
  lv_style_set_text_color(&power_style, lv_color_hex(POWER_COLOR));
  lv_style_set_border_color(&power_style, lv_color_hex(BORDER_COLOR));
  lv_style_set_border_opa(&power_style, LV_OPA_50);
  lv_style_set_border_width(&power_style, 1);
  lv_style_set_pad_top(&power_style, 7);
  lv_style_set_pad_left(&power_style, 10);

  lv_style_set_bg_opa(&status_style, LV_OPA_COVER);
  lv_style_set_bg_color(&status_style, lv_color_hex(0x0));
  lv_style_set_width(&status_style, lv_pct(100));
  lv_style_set_height(&status_style, 38);
  lv_style_set_text_color(&status_style, lv_color_hex(0xa0a0a0));
  lv_style_set_pad_top(&status_style, 5);
  lv_style_set_pad_left(&status_style, 10);

  lv_style_set_text_font(&lb_mark_style, &TIPS_FONT);
  lv_style_set_bg_opa(&lb_mark_style, LV_OPA_TRANSP);
  lv_style_set_bg_color(&lb_mark_style, lv_color_black());
  lv_style_set_width(&lb_mark_style, 48);
  lv_style_set_height(&lb_mark_style, 44);
  lv_style_set_text_color(&lb_mark_style, lv_color_hex(TIPS_TEXT_COLOR));
  lv_style_set_border_color(&lb_mark_style, lv_color_hex(BORDER_COLOR));
  lv_style_set_border_opa(&lb_mark_style, LV_OPA_50);
  lv_style_set_border_width(&lb_mark_style, 1);
  lv_style_set_text_align(&lb_mark_style, LV_TEXT_ALIGN_CENTER);
  lv_style_set_pad_top(&lb_mark_style, 16);
  lv_style_set_pad_left(&lb_mark_style, 0);

  lv_style_set_bg_opa(&num_style, LV_OPA_COVER);
  lv_style_set_bg_color(&num_style, lv_color_hex(0x212121));
  lv_style_set_width(&num_style, 48);
  lv_style_set_height(&num_style, 48);
  lv_style_set_text_font(&num_style, &MAIN_BIG_NUM_FONT);
  lv_style_set_text_align(&num_style, LV_TEXT_ALIGN_CENTER);
  lv_style_set_pad_top(&num_style, 9);
  lv_style_set_pad_left(&num_style, 0);

  // 设置页样式
  lv_style_set_bg_opa(&style_radio, LV_OPA_COVER);
  lv_style_set_bg_color(&style_radio, lv_color_hex(0x212121));
  lv_style_set_width(&style_radio, 100);
  lv_style_set_height(&style_radio, 50);
  lv_style_set_text_color(&style_radio, lv_color_hex(0x878787));
  lv_style_set_text_font(&style_radio, &MAIN_BIG_NUM_FONT);
  lv_style_set_text_align(&style_radio, LV_TEXT_ALIGN_CENTER);
  lv_style_set_pad_top(&style_radio, 10);
  lv_style_set_pad_left(&style_radio, 12);

  lv_style_set_bg_color(&style_radio_chk, lv_color_hex(HIGHLIGHT_COLOR));
  lv_style_set_text_color(&style_radio_chk, lv_color_hex(0xffffff));

  lv_style_set_bg_opa(&style_text_area, LV_OPA_TRANSP);
  lv_style_set_width(&style_text_area, 120);
  lv_style_set_height(&style_text_area, 56);
  lv_style_set_text_color(&style_text_area, lv_color_hex(0xc0c0c0));
  lv_style_set_text_font(&style_text_area, &MAIN_BIG_NUM_FONT);
  lv_style_set_text_align(&style_text_area, LV_TEXT_ALIGN_CENTER);
  lv_style_set_pad_top(&style_text_area, 11);
  lv_style_set_radius(&style_text_area, 0);
  lv_style_set_border_width(&style_text_area, 1);
  lv_style_set_border_color(&style_text_area, lv_color_hex(0x404040));

  lv_style_set_border_color(&style_text_area_focus, lv_color_hex(HIGHLIGHT_COLOR));

  lv_style_set_bg_color(&style_label, lv_color_hex(0x202020));
  lv_style_set_bg_opa(&style_label, LV_OPA_COVER);
  lv_style_set_width(&style_label, 120);
  lv_style_set_height(&style_label, 53);
  lv_style_set_text_color(&style_label, lv_color_hex(0xa0a0a0));
  lv_style_set_text_font(&style_label, &SETTING_TIPS_FONT);
  lv_style_set_text_align(&style_label, LV_TEXT_ALIGN_CENTER);
  lv_style_set_pad_top(&style_label, 19);
  lv_style_set_border_width(&style_label, 0);

  main_cont = lv_obj_create(screen_usb_hub);
  lv_obj_remove_style_all(main_cont);
  lv_obj_set_size(main_cont, SCREEN_RES_HOR * 2, SCREEN_RES_VER);
  lv_obj_set_pos(main_cont, 0, 0);

  usb_cont = lv_obj_create(main_cont);
  lv_obj_remove_style_all(usb_cont);
  lv_obj_set_size(usb_cont, SCREEN_RES_HOR, SCREEN_RES_VER);
  lv_obj_align(usb_cont, LV_ALIGN_LEFT_MID, 0, 0);
  lv_obj_set_style_bg_opa(usb_cont, LV_OPA_TRANSP, 0);
  lv_obj_set_flex_flow(usb_cont, LV_FLEX_FLOW_ROW_WRAP);
  lv_obj_set_flex_align(usb_cont, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_SPACE_BETWEEN);
  lv_obj_clear_flag(usb_cont, LV_OBJ_FLAG_SCROLLABLE);

  for (int i = 0; i < USB_PORT_NUMS; i++) {
    btn_usb[i] = lv_btn_create(usb_cont);
    lv_obj_add_style(btn_usb[i], &btn_style, LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(btn_usb[i], lv_color_hex(PORT_OFF_COLOR), LV_STATE_USER_1);      // 关断
    lv_obj_set_style_text_color(btn_usb[i], lv_color_hex(PORT_ALERT_COLOR), LV_STATE_USER_2);  // 警告
    lv_obj_set_style_bg_color(btn_usb[i], lv_color_hex(PORT_OC_COLOR), LV_STATE_USER_3);       // 过流

    lv_obj_clear_flag(btn_usb[i], LV_OBJ_FLAG_SCROLLABLE);

    btnState[i] = inaData[i].portStatus;

    lv_obj_t *lb_num = lv_label_create(btn_usb[i]);
    lv_obj_add_style(lb_num, &num_style, 0);
    lv_label_set_text_fmt(lb_num, "%d", i + 1);
    uint16_t base_y = 0;
    if (i == 0) {
      base_y = 0;
      lv_obj_align(lb_num, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
    } else if (i == 1) {
      base_y = 0;
      lv_obj_align(lb_num, LV_ALIGN_BOTTOM_LEFT, 0, 0);
    } else if (i == 2) {
      base_y = 62;
      lv_obj_align(lb_num, LV_ALIGN_TOP_RIGHT, 0, 0);
    } else {
      base_y = 62;
      lv_obj_align(lb_num, LV_ALIGN_TOP_LEFT, 0, 0);
    }

    if (btnState[i] == USB_PORT_FAIL) {
      chartCurrent[i] = NULL;
      chartCurrentSer[i] = NULL;
      lb_voltage[i] = NULL;
      lb_current[i] = NULL;
      lb_power[i] = NULL;

      continue;
    }

    lv_obj_add_event_cb(btn_usb[i], btn_event_handler, LV_EVENT_CLICKED, &inaData[i]);

    chartCurrent[i] = lv_chart_create(btn_usb[i]);
    lv_obj_remove_style_all(chartCurrent[i]);
    lv_obj_set_style_bg_opa(chartCurrent[i], LV_OPA_COVER, LV_PART_MAIN);
    lv_obj_set_style_bg_color(chartCurrent[i], lv_color_hex(0x0), LV_PART_MAIN);
    lv_obj_set_size(chartCurrent[i], 158, 48);
    if (i == 0) {
      lv_obj_align(chartCurrent[i], LV_ALIGN_BOTTOM_LEFT, 0, 0);
    } else if (i == 1) {
      lv_obj_align(chartCurrent[i], LV_ALIGN_BOTTOM_RIGHT, 0, 0);
    } else if (i == 2) {
      lv_obj_align(chartCurrent[i], LV_ALIGN_TOP_LEFT, 0, 0);
    } else {
      lv_obj_align(chartCurrent[i], LV_ALIGN_TOP_RIGHT, 0, 0);
    }
    lv_chart_set_type(chartCurrent[i], LV_CHART_TYPE_LINE);
    lv_chart_set_point_count(chartCurrent[i], CHART_TEMP_LEN);
    lv_chart_set_range(chartCurrent[i], LV_CHART_AXIS_PRIMARY_Y, inaData[i].chartMin, inaData[i].chartMax);
    lv_obj_add_event_cb(chartCurrent[i], chart_draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, &inaData[i]);
    lv_chart_set_update_mode(chartCurrent[i], LV_CHART_UPDATE_MODE_SHIFT);
    chartCurrentSer[i] = lv_chart_add_series(chartCurrent[i], lv_color_hex(CHART_LINE_COLOR), LV_CHART_AXIS_PRIMARY_Y);

    lb_voltage[i] = lv_label_create(btn_usb[i]);
    lv_label_set_text(lb_voltage[i], "");
    lv_obj_add_style(lb_voltage[i], &voltage_style, 0);
    lv_obj_align(lb_voltage[i], LV_ALIGN_TOP_RIGHT, 0, base_y);
    lv_obj_set_style_text_color(lb_voltage[i], lv_color_hex(TIPS_TEXT_COLOR), LV_STATE_USER_1);  // 关断

    lv_obj_t *unit_v = lv_label_create(btn_usb[i]);
    lv_obj_add_style(unit_v, &lb_mark_style, 0);
    lv_label_set_text(unit_v, "VBUS");
    lv_obj_align_to(unit_v, lb_voltage[i], LV_ALIGN_OUT_LEFT_MID, -8, 0);

    lb_current[i] = lv_label_create(btn_usb[i]);
    lv_label_set_text(lb_current[i], "");
    lv_obj_add_style(lb_current[i], &current_style, 0);
    lv_obj_align(lb_current[i], LV_ALIGN_TOP_RIGHT, 0, 54 + base_y);
    lv_obj_set_style_text_color(lb_current[i], lv_color_hex(TIPS_TEXT_COLOR), LV_STATE_USER_1);  // 关断

    lv_obj_t *unit_a = lv_label_create(btn_usb[i]);
    lv_obj_add_style(unit_a, &lb_mark_style, 0);
    lv_label_set_text(unit_a, "IBUS");
    lv_obj_align_to(unit_a, lb_current[i], LV_ALIGN_OUT_LEFT_MID, -8, 0);

    lb_power[i] = lv_label_create(btn_usb[i]);
    lv_label_set_text(lb_power[i], "");
    lv_obj_add_style(lb_power[i], &power_style, 0);
    lv_obj_align(lb_power[i], LV_ALIGN_TOP_RIGHT, 0, 108 + base_y);
    lv_obj_set_style_text_color(lb_power[i], lv_color_hex(TIPS_TEXT_COLOR), LV_STATE_USER_1);  // 关断

    lv_obj_t *unit_p = lv_label_create(btn_usb[i]);
    lv_obj_add_style(unit_p, &lb_mark_style, 0);
    lv_label_set_text(unit_p, "PWR");
    lv_obj_align_to(unit_p, lb_power[i], LV_ALIGN_OUT_LEFT_MID, -8, 0);

    set_port_btn_status(i, btnState[i]);
  }

  setting_cont = lv_obj_create(main_cont);
  lv_obj_remove_style_all(setting_cont);
  lv_obj_set_style_bg_opa(setting_cont, LV_OPA_COVER, 0);
  lv_obj_set_style_bg_color(setting_cont, lv_color_black(), 0);

  lv_obj_set_size(setting_cont, SCREEN_RES_HOR, SCREEN_RES_VER);
  lv_obj_align(setting_cont, LV_ALIGN_RIGHT_MID, 0, 0);
  lv_obj_clear_flag(setting_cont, LV_OBJ_FLAG_SCROLLABLE);

  lv_obj_t *bottom_cont = lv_obj_create(setting_cont);
  lv_obj_remove_style_all(bottom_cont);
  lv_obj_set_flex_flow(bottom_cont, LV_FLEX_FLOW_ROW);

  lv_obj_set_flex_align(bottom_cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
  lv_obj_set_size(bottom_cont, SCREEN_RES_HOR, 50);
  lv_obj_align(bottom_cont, LV_ALIGN_BOTTOM_MID, 0, -16);

  lv_obj_add_event_cb(bottom_cont, port_radio_event_handler, LV_EVENT_CLICKED, NULL);

  char txt[10] = { 0 };
  for (int i = 0; i < USB_PORT_NUMS; i++) {
    snprintf(txt, 10, "%d", i + 1);
    radiobutton_create(bottom_cont, txt);
  }

  lv_obj_add_state(lv_obj_get_child(bottom_cont, curr_setting_port), LV_STATE_CHECKED);

  for (int i = 0; i < 4; i++) {
    lv_obj_t *lb = lv_label_create(setting_cont);
    lv_obj_add_style(lb, &style_label, 0);
    lv_label_set_text(lb, tips[i]);
    lv_obj_set_pos(lb, 16, 16 + i * 59);

    ta_setting[i] = lv_textarea_create(setting_cont);

    lv_textarea_set_one_line(ta_setting[i], true);
    lv_textarea_set_max_length(ta_setting[i], 4);
    lv_obj_set_pos(ta_setting[i], 140, 16 + i * 59);
    lv_obj_add_style(ta_setting[i], &style_text_area, LV_STATE_DEFAULT);
    lv_obj_add_style(ta_setting[i], &style_text_area_focus, LV_STATE_FOCUSED);
    lv_obj_set_style_border_color(ta_setting[i], lv_color_hex(0xffffff), (lv_style_selector_t)LV_PART_CURSOR | (lv_style_selector_t)LV_STATE_FOCUSED);
    lv_obj_add_event_cb(ta_setting[i], ta_event_cb, LV_EVENT_ALL, NULL);
  }

  draw_current_setting();

  lv_obj_t *lb = lv_label_create(setting_cont);
  lv_obj_set_style_text_font(lb, &SETTING_TIPS_FONT, 0);
  lv_obj_set_style_text_color(lb, lv_color_hex(0x808080), 0);
  lv_label_set_text(lb, "设置USB端口相关电流值(范围：0-2000)，单位毫安");
  lv_obj_set_pos(lb, 16, 280);

  lb_ctt = lv_label_create(setting_cont);
  lv_obj_set_style_text_font(lb_ctt, &SETTING_TIPS_FONT, 0);
  lv_obj_set_style_text_color(lb_ctt, lv_color_hex(0xff0000), 0);
  lv_label_set_text(lb_ctt, "");
  lv_obj_set_pos(lb_ctt, 16, 320);

  kb = lv_keyboard_create(setting_cont);
  lv_obj_set_size(kb, 200, 240);
  lv_obj_align(kb, LV_ALIGN_TOP_RIGHT, -11, 11);
  lv_obj_set_style_bg_color(kb, lv_color_black(), LV_PART_MAIN);
  lv_obj_set_style_bg_color(kb, lv_color_hex(0x212121), (lv_style_selector_t)LV_PART_ITEMS | (lv_style_selector_t)LV_STATE_DEFAULT);
  lv_obj_set_style_text_color(kb, lv_color_hex(0xffffff), LV_PART_ITEMS);
  lv_obj_set_style_bg_color(kb, lv_color_hex(0x606060), (lv_style_selector_t)LV_PART_ITEMS | (lv_style_selector_t)LV_STATE_PRESSED);
  lv_obj_set_style_radius(kb, 0, LV_PART_ITEMS);

  lv_keyboard_set_map(kb, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl);
  lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_1);

  lv_keyboard_set_textarea(kb, ta_setting[0]);
  lv_obj_add_event_cb(screen_usb_hub, page_event_handler, LV_EVENT_ALL, NULL);

  _usb_hub_timer = lv_timer_create(usb_hub_timer_timeout, USB_HUB_HWMON_UPDATE_INV, NULL);
  lv_timer_set_repeat_count(_usb_hub_timer, -1);
}

void load_ui() {
  setup_screen_usb_hub();
  lv_scr_load(screen_usb_hub);
}